
#include "videoThreadProxy.h"
#include "ParserPacket.hpp"
#include "RTPDecoderWrapper.hpp"
#include "RTPSharePicture.hpp"
#include "RtpPacket.hpp"
#include "UdpSocketWrapper.hpp"
#include "hiScopeGuard.h"
#include <unistd.h>

static const char *MY_IP = "127.0.0.1";

bool VideoThreadProxy::start(VideoOption &option) {
    this->video_option = &option;
    this->thread.start([&]() { this->run(); });
    return true;
}

void VideoThreadProxy::stop() { thread.stop(); }

void VideoThreadProxy::run() {
    Hi::RTPSharePicture handle;
    Hi::RTPDecoderWrapper decoder;
    decoder.Start(handle, this->video_option->get_width(),
                  this->video_option->get_height(), nullptr);

    ON_SCOPE_EXIT([&]() { decoder.Stop(); });
    bool isSuccess = handle.Start(this->video_option->get_share_path(),
                                  this->video_option->get_width(),
                                  this->video_option->get_height());
    if (!isSuccess) {
        return;
    }
    ON_SCOPE_EXIT([&]() { handle.Stop(); });
    UdpSocketWrapper *udp = new UdpSocketWrapper();
    int ret = udp->Listen(MY_IP, this->video_option->get_port(),
                          [&](const uint8_t *data, size_t len,
                              const struct sockaddr *addr,
                              UdpSocketWrapper *wrapper) {
                              this->on_receive(data, len, decoder);
                          });

    if (ret != 0) {
        return;
    }
    ON_SCOPE_EXIT([&]() { udp->Destroy(); });

    while (!this->thread.want_exit()) {
        sleep(1);
    }
}

void VideoThreadProxy::on_receive(const uint8_t *data, size_t len,
                                  Hi::RTPDecoderWrapper &decoder) {
    Hi::RtpPacket *packet = Hi::hi_RtpPacket_parse(data, len);
    if (packet == nullptr) {
        return;
    }
    decoder.Decode(packet);
    Hi::hi_RtpPacket_release(&packet);
}